"""
# -*- coding: utf-8 -*-
# @Time    : 2023/5/21 20:23
# @Author  : 王摇摆
# @FileName: SVM.py
# @Software: PyCharm
# @Blog    ：https://blog.csdn.net/weixin_44943389?type=blog
"""
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.font_manager import FontProperties

def createTrainDatas(W, b, start, end, size=10):
    """
    创建线性可分的训练数据集
    args:
        W - 目标权重系数
        b - 偏移量
        start - 最小值
        end - 最大值
        size - 训练数据集大小
    return:
        X - 训练集特征值
        y - 训练集目标值
    """
    np.random.seed(42)
    X = np.random.uniform(start, end, (size, W.shape[0]))
    y = np.sign(X.dot(W) + b)
    return X, y


def buildLine(W, b, start, end, size=100):
    """
    构建一条指定的直线
    args:
        W - 权重系数
        b - 偏移量
        start - 最小值
        end - 最大值
        size - 组成线的点的数量
        w0 * x0 + w1 * x1 + b = 0
    """
    x0 = np.linspace(start, end, size)
    if W[1] == 0:
        x0 = np.ones(size) * (-b / W[0])
        x1 = np.zeros(size)
    else:
        x1 = -(b + W[0] * x0) / W[1]
    return x0, x1


# 坐标轴起始点
start = -10
# 坐标轴结束点
end = 10
# 目标权重系数
W = np.array([5, 4])
b = 0
# 创建线性可分的训练数据集
X, y = createTrainDatas(W, b, start, end, size=20)



font_path = 'C:\Windows\Fonts\simkai.ttf'
# 加载中文字体
font = FontProperties(fname=font_path)
fig, ax = plt.subplots()
ax.set_facecolor('#f8f9fa')

x1 = X[y == -1][:, 0]
y1 = X[y == -1][:, 1]
x2 = X[y == 1][:, 0]
y2 = X[y == 1][:, 1]
p1 = plt.scatter(x1, y1, c='#e63946', marker='o', s=20)
p2 = plt.scatter(x2, y2, c='#457b9d', marker='x', s=20)

x3, y3 = buildLine([0.39, 0.26], -0.13, start, end)
x4, y4 = buildLine([0.19, 0.18], -0.12, start, end)
p3, = plt.plot(x3, y3, '#457b9d')
p4, = plt.plot(x4, y4, '#e63946')

ax.set_title('硬间隔支持向量机', color='#264653',font=font,fontsize=18)
ax.set_xlabel('X1', color='#264653')
ax.set_ylabel('X2', color='#264653')
ax.tick_params(labelcolor='#264653')
plt.legend([p1, p2, p3, p4], ["-EXP1", "EXP1", "A", "B"], loc="upper right")
plt.show()
